<template>
	<div
		:class="[
			'app-editor-container',
			'app-map-picker',
			`app-map-picker-${name}`,
		]"
	>
		<AppInput
			:value="value"
			:readOnly="true"
			:disabled="disabled"
			:placeholder="placeholder"
			@click="handleMapShow"
		></AppInput>
		<a-modal
			v-model:visible="visible"
			:title="$t('common.mappicker.title', '请选择地址')"
			width="80%"
			wrapClassName="map-picker-dialog-warp"
			@ok="handleOk"
		>
			<div class="app-map-picker-search">
				<div class="search-toolbar">
					<a-form-item-rest>
						<a-input
							v-model:value="searchKey"
							:placeholder="placeholder"
							@change="onSearch"
						></a-input>
					</a-form-item-rest>
					<a-button @click="resetMap">{{
						$t('common.mappicker.reset', '重置')
					}}</a-button>
				</div>
				<div id="map__result" v-show="resultShow">
					<div
						class="search-result-item"
						v-for="(item, index) in items"
						:key="index"
						@click="() => searchClick(item)"
					>
						<p class="result-item__cityname">{{ item.name }}</p>
						<p class="result-item__addresss">
							{{ $t('common.mappicker.searchaddress', '地址') }}：{{
								item.address
							}}
						</p>
						<p class="result-item__tel" v-if="item.tel">
							{{ $t('common.mappicker.searchtel', '电话') }}：{{ item.tel }}
						</p>
					</div>
				</div>
			</div>

			<div class="container">
				<div id="map-container"></div>
			</div>
		</a-modal>
	</div>
</template>
<script setup lang="ts">
import { Ref, ref, shallowRef } from 'vue';
import { mapPickerProps } from './map-picker';
import { IEvent } from '@/core';
import { useEditorTypeParams } from '@/hooks/use-editor';
interface EditorEmit {
	(name: 'component-action', value: IEvent<string>): void;
}
const props = defineProps(mapPickerProps);
const emit = defineEmits<EditorEmit>();
// 类型校验
const { validateConfig } = useEditorTypeParams();
validateConfig();
const visible: Ref<Boolean> = ref(false); //控制弹窗显示
const resultShow: Ref<Boolean> = ref(false); //控制搜索结果显示
const searchKey: Ref<String> = ref(''); //搜索词
const items: Ref<any> = ref([]); //搜索结果
let amap: any = shallowRef(null);
let myMap: any = shallowRef(null);
let geocoder: any = shallowRef(null);
let placeSearch: any = shallowRef(null);
const marker: Ref<any> = ref({});
let mapMarker: any = shallowRef(null);
let reset: boolean = false;
//获取经度
const longitude = computed(() => {
	if (props.valueItemNames) {
		return props.valueItemNames.split(',')[0];
	}
});
//获取维度
const latitude = computed(() => {
	if (props.valueItemNames) {
		return props.valueItemNames.split(',')[1];
	}
});

/**
 * 初始化地图
 */
const initMap = () => {
	let position: any = null;
	if (props.value) {
		searchKey.value = props.value;
	}
	if (
		props.data &&
		longitude.value &&
		props.data[`${longitude.value}`] &&
		latitude.value &&
		props.data[`${latitude.value}`] &&
		props.data
	) {
		position = [
			props.data[`${longitude.value}`],
			props.data[`${latitude.value}`],
		];
	}

	//初始化地图
	const mapOpt = {
		viewMode: '2D',
		zoom: 12,
	};
	// 存在回显地址 不存在则默认当前地址
	if (position) {
		Object.assign(mapOpt, { center: position });
	}
	amap = (window as any).AMap;
	myMap = new amap.Map('map-container', mapOpt);
	geocoder = new amap.Geocoder({ extensions: 'all' });
	placeSearch = new amap.PlaceSearch({
		pageSize: 5,
		city: App.ts('common.mappicker.city'),
		citylimit: false,
		renderStyle: 'newpc',
	});
	initEvents();
	if (position?.length > 1) {
		handleMapMark(position[0], position[1]);
	} else {
		initDefaultLocation();
	}
};

const initDefaultLocation = () => {
	// 设置当前城市地址
	amap.plugin('AMap.Geolocation', function () {
		var geolocation = new amap.Geolocation({
			showButton: false,
			circleOptions: {
				fillOpacity: 0,
				strokeColor: '#00',
				bubble: true,
			},

			zoomToAccuracy: true, //定位成功后是否自动调整地图视野到定位点
		});
		myMap.addControl(geolocation);
		geolocation.getCurrentPosition();
	});
};

//初始化地图事件
const initEvents = () => {
	myMap.on('click', handleMapClick);
};

//处理地图点击
const handleMapClick = ($event: any) => {
	if (!$event || !$event.lnglat) {
		return;
	}
	reset = false;
	handleMapMark($event.lnglat.lng, $event.lnglat.lat);
};

//处理地图标点
const handleMapMark = async (lng: any, lat: any, showList: boolean = false) => {
	const address = await getAddress(lng, lat).catch((error) => {
		console.warn(error);
	});
	if (!address) {
		return;
	}
	//设置当前地址名
	searchKey.value = address as string;
	//关闭搜索结果
	resultShow.value = showList;
	//保存当前地址经纬度
	marker.value = {
		position: [lng, lat],
		address: address,
	};
	myMap.remove(mapMarker);
	mapMarker = new amap.Marker({
		content:
			"<div id='custom-mark'> <img src='//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png'><span class='input-map__marker'>" +
			address +
			'</span></div>',
		position: [lng, lat],
	});
	myMap.add(mapMarker);
	myMap.setCenter([lng, lat]);
};

//点击模态确定
const handleOk = () => {
	visible.value = false;
	if (props.valueItemNames) {
		emit('component-action', {
			name: props.valueItemNames.split(',')[0],
			action: 'valueChange',
			data: reset ? '' : marker.value.position[0],
		});
		emit('component-action', {
			name: props.valueItemNames.split(',')[1],
			action: 'valueChange',
			data: reset ? '' : marker.value.position[1],
		});
	}
	emit('component-action', {
		name: `${props.name}`,
		action: 'valueChange',
		data: reset ? '' : marker.value.address,
	});
};

//显示模态
const handleMapShow = () => {
	if (props.disabled || props.readOnly) {
		return;
	}
	visible.value = true;
	resultShow.value = false;
	nextTick(() => {
		initMap();
	});
};

//调用服务搜索地点
const onSearch = (event: any) => {
	if (!event || !event.target) {
		return;
	}
	const { value } = event.target;
	placeSearch.search(value, (status: any, result: any) => {
		if (status == 'complete' && result.info == 'OK') {
			resultShow.value = true;
			items.value = result.poiList.pois;
		}
	});
};

//重置搜索词
const resetMap = () => {
	searchKey.value = '';
	reset = true;
	initDefaultLocation();
};

//根据经纬度获取详细地址名
const getAddress = (lng: any, lat: any) => {
	return new Promise((resolve: any, reject: any) => {
		geocoder.getAddress([lng, lat], (status: any, result: any) => {
			if (status === 'complete' && result.info === 'OK') {
				if (result && result.regeocode) {
					const address = result.regeocode.formattedAddress;
					resolve(address);
				}
			}
		});
	});
};

const searchClick = (item: any) => {
	const { address, location } = item;
	searchKey.value = address;
	handleMapMark(location.lng, location.lat);
};
</script>